package com.trinh.utils.crypto.cryptors;

import com.trinh.utils.crypto.config.KeyConfig;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @Author: TrinhRae
 * @Package: com.trinh.utils.crypto.rsa
 * @Project: generaltools
 * @Date: 2025/6/23 14:06
 */
public class RSASignUtil {
    private final KeyConfig keyConfig;

    public RSASignUtil(KeyConfig keyConfig) {
        this.keyConfig = keyConfig;
    }

    /**
     * 私钥签名（SHA256withRSA）
     */
    public String sign(String data) throws Exception {
        PrivateKey privateKey = getPrivateKeyFromBase64(keyConfig.getPrivateKey());
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(signature.sign());
    }

    /**
     * 公钥验签
     */
    public boolean verify(String data, String signatureStr) throws Exception {
        PublicKey publicKey = getPublicKeyFromBase64(keyConfig.getPublicKey());
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));
        return signature.verify(Base64.getDecoder().decode(signatureStr));
    }

    /**
     * 从 Base64 编码恢复公钥对象
     */
    public PublicKey getPublicKeyFromBase64(String base64Key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64Key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        return KeyFactory.getInstance("RSA").generatePublic(keySpec);
    }

    /**
     * 从 Base64 编码恢复私钥对象
     */
    public PrivateKey getPrivateKeyFromBase64(String base64Key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64Key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
    }
}
